package cn.anecansaitin.whimsy.mixin.client;

import cn.anecansaitin.whimsy.client.event.ModClientEventHooks;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Set;
import java.util.UUID;

@Mixin(AbstractClientPlayer.class)
public abstract class AbstractClientPlayerMixin {
    @Redirect(method = "getFieldOfViewModifier", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;getAttributeValue(Lnet/minecraft/world/entity/ai/attributes/Attribute;)D", ordinal = 0))
    public double redirect$getFieldOfViewModifier(AbstractClientPlayer instance, Attribute attribute) {
        AttributeInstance attribute1 = instance.getAttribute(attribute);
        Set<UUID> uuids = ModClientEventHooks.onFOVModifierWithSpeed();

        if (uuids.isEmpty()) {
            return attribute1.getValue();
        }

        double add = 0;
        double multiplyBase = 0;
        double multiplyTotal = 1;

        //获取需要剔除的值
        for (UUID uuid : uuids) {
            AttributeModifier modifier = attribute1.getModifier(uuid);

            if (modifier == null) {
                continue;
            }

            switch (modifier.getOperation()) {
                case ADDITION -> add += modifier.getAmount();
                case MULTIPLY_BASE -> multiplyBase += modifier.getAmount();
                case MULTIPLY_TOTAL -> multiplyTotal *= (modifier.getAmount() + 1);
            }
        }

        double d0 = attribute1.getBaseValue() - add;

        for(AttributeModifier attributemodifier : attribute1.getModifiers(AttributeModifier.Operation.ADDITION)) {
            d0 += attributemodifier.getAmount();
        }

        double d1 = d0;

        for(AttributeModifier attributemodifier : attribute1.getModifiers(AttributeModifier.Operation.MULTIPLY_BASE)) {
            d1 += d0 * attributemodifier.getAmount();
        }

        d1 -= d0 * multiplyBase;

        for(AttributeModifier attributemodifier : attribute1.getModifiers(AttributeModifier.Operation.MULTIPLY_TOTAL)) {
            d1 *= 1.0 + attributemodifier.getAmount();
        }

        d1 /= multiplyTotal;

        return attribute.sanitizeValue(d1);
    }
}
